package com.ruoyi.system.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.system.mapper.SysDockerTemplateMapper;
import com.ruoyi.system.domain.SysDockerTemplate;
import com.ruoyi.system.service.ISysDockerTemplateService;
import com.ruoyi.system.service.ISyncServerService;
import com.ruoyi.system.utils.DockerMigrationLogger;

/**
 * Docker容器模板Service业务层处理
 * 
 * @author ruoyi
 */
@Service
public class SysDockerTemplateServiceImpl implements ISysDockerTemplateService 
{
    @Autowired
    private SysDockerTemplateMapper dockerTemplateMapper;
    
    @Autowired
    private ISyncServerService syncServerService;

    /**
     * 查询Docker容器模板
     * 
     * @param templateId Docker容器模板ID
     * @return Docker容器模板
     */
    @Override
    public SysDockerTemplate selectDockerTemplateById(Long templateId)
    {
        return dockerTemplateMapper.selectDockerTemplateById(templateId);
    }

    /**
     * 查询Docker容器模板列表
     * 
     * @param dockerTemplate Docker容器模板
     * @return Docker容器模板
     */
    @Override
    public List<SysDockerTemplate> selectDockerTemplateList(SysDockerTemplate dockerTemplate)
    {
        return dockerTemplateMapper.selectDockerTemplateList(dockerTemplate);
    }

    /**
     * 新增Docker容器模板
     * 
     * @param dockerTemplate Docker容器模板
     * @return 结果
     */
    @Override
    public int insertDockerTemplate(SysDockerTemplate dockerTemplate)
    {
        dockerTemplate.setCreateTime(DateUtils.getNowDate());
        return dockerTemplateMapper.insertDockerTemplate(dockerTemplate);
    }

    /**
     * 修改Docker容器模板
     * 
     * @param dockerTemplate Docker容器模板
     * @return 结果
     */
    @Override
    public int updateDockerTemplate(SysDockerTemplate dockerTemplate)
    {
        dockerTemplate.setUpdateTime(DateUtils.getNowDate());
        return dockerTemplateMapper.updateDockerTemplate(dockerTemplate);
    }

    /**
     * 删除Docker容器模板对象
     * 
     * @param templateId Docker容器模板ID
     * @return 结果
     */
    @Override
    public int deleteDockerTemplateById(Long templateId)
    {
        return dockerTemplateMapper.deleteDockerTemplateById(templateId);
    }

    /**
     * 批量删除Docker容器模板
     * 
     * @param templateIds 需要删除的Docker容器模板ID
     * @return 结果
     */
    @Override
    public int deleteDockerTemplateByIds(Long[] templateIds)
    {
        return dockerTemplateMapper.deleteDockerTemplateByIds(templateIds);
    }
    
    /**
     * 从模板创建Docker容器
     * 
     * @param serverId 服务器ID
     * @param templateId 模板ID
     * @param containerName 容器名称
     * @param customParams 自定义参数
     * @return 结果
     */
    @Override
    public Map<String, Object> createContainerFromTemplate(Long serverId, Long templateId, String containerName, Map<String, String> customParams)
    {
        Map<String, Object> result = new HashMap<>();
        result.put("success", false);
        result.put("message", "");
        result.put("showProcess", true); // 添加显示过程标志
        result.put("processId", System.currentTimeMillis()); // 添加过程ID，用于前端识别
        
        // 检查参数
        if (serverId == null || templateId == null)
        {
            result.put("message", "参数错误：服务器ID和模板ID不能为空");
            return result;
        }
        
        // 获取模板信息
        SysDockerTemplate template = dockerTemplateMapper.selectDockerTemplateById(templateId);
        if (template == null)
        {
            result.put("message", "模板不存在");
            return result;
        }
        
        // 记录部署开始
        DockerMigrationLogger.logContainerMigrationStep(serverId, null, containerName, 
            "部署开始", "开始从模板 [" + template.getTemplateName() + "] 部署容器");
        
        String executeCommand;
        
        // 判断是否使用Docker Compose
        if ("1".equals(template.getUseCompose()))
        {
            // Docker Compose模式
            executeCommand = createContainerWithCompose(template, containerName, customParams);
        }
        else
        {
            // 普通Docker模式
            executeCommand = createContainerWithDocker(template, containerName, customParams);
        }
        
        // 记录执行的命令
        DockerMigrationLogger.logContainerMigrationStep(serverId, null, containerName, 
            "执行命令", executeCommand);
        
        // 执行命令，对所有Docker容器创建都使用超时参数
        Map<String, Object> executeResult = syncServerService.executeCommandWithTimeout(serverId, executeCommand, 300); // 5分钟超时
        
        // 处理结果
        if (executeResult != null && (Boolean) executeResult.getOrDefault("success", false))
        {
            result.put("success", true);
            result.put("message", "容器创建成功");
            
            // 记录部署成功
            String stdout = (String) executeResult.getOrDefault("stdout", "");
            DockerMigrationLogger.logContainerMigrationEnd(serverId, null, containerName, 
                true, "容器创建成功: " + (stdout.length() > 100 ? stdout.substring(0, 100) + "..." : stdout));
        }
        else if (executeResult != null && Boolean.TRUE.equals(executeResult.get("timeout")))
        {
            // 超时情况下，也返回成功，但附带说明信息
            result.put("success", true);
            result.put("message", "命令已发送，容器正在创建中，请稍后查看结果");
            
            // 记录部署超时
            DockerMigrationLogger.logContainerMigrationStep(serverId, null, containerName, 
                "部署超时", "命令执行超时，容器正在后台创建中");
        }
        else
        {
            String errorMsg = executeResult != null ? (String) executeResult.getOrDefault("stderr", "未知错误") : "执行命令失败";
            result.put("message", errorMsg);
            
            // 记录部署失败
            DockerMigrationLogger.logContainerMigrationEnd(serverId, null, containerName, 
                false, "容器创建失败: " + errorMsg);
        }
        
        // 添加部署日志到结果中
        result.put("logs", executeResult != null ? executeResult.getOrDefault("stdout", "") : "");
        result.put("errors", executeResult != null ? executeResult.getOrDefault("stderr", "") : "");
        
        return result;
    }
    
    /**
     * 使用Docker Compose模式创建容器
     * 
     * @param template Docker模板
     * @param deployName 部署名称
     * @param customParams 自定义参数
     * @return 命令字符串
     */
    private String createContainerWithCompose(SysDockerTemplate template, String deployName, Map<String, String> customParams)
    {
        if (StringUtils.isEmpty(template.getComposeConfig()))
        {
            return "echo 'Compose配置为空，无法部署'";
        }
        
        // 生成一个唯一的目录名
        String dirName = (StringUtils.isNotEmpty(deployName) ? deployName : template.getTemplateName()) + "-" + System.currentTimeMillis();
        dirName = dirName.replaceAll("[^a-zA-Z0-9_-]", "_"); // 确保目录名有效
        
        // 处理Docker Compose配置中可能的容器名称冲突
        String composeConfig = template.getComposeConfig();
        
        // 如果配置中有container_name定义，添加时间戳避免冲突
        String timestamp = String.valueOf(System.currentTimeMillis());
        composeConfig = composeConfig.replaceAll("container_name:\\s*([\"']?)([\\w-]+)\\1", 
                                               "container_name: $2-" + timestamp);
        
        StringBuilder command = new StringBuilder();
        
        // 提取并创建挂载目录，设置权限
        command.append("# 自动创建挂载目录并设置权限\n");
        
        // 从Compose配置中提取卷映射
        String[] lines = composeConfig.split("\n");
        for (String line : lines) {
            if (line.trim().startsWith("- ") && line.contains(":")) {
                String volumeMapping = line.trim().substring(2).trim();
                // 只处理主机路径:容器路径格式的挂载
                if (volumeMapping.startsWith("/") && volumeMapping.contains(":")) {
                    String hostPath = volumeMapping.substring(0, volumeMapping.indexOf(":"));
                    command.append("mkdir -p ").append(hostPath).append(" && ");
                    command.append("chmod -R 777 ").append(hostPath).append(" && ");
                }
            }
        }
        
        // 特殊处理Elasticsearch的虚拟内存限制
        if (template.getImageName().toLowerCase().contains("elasticsearch")) {
            command.append("sysctl -w vm.max_map_count=262144 || true && ");
        }
        
        command.append("mkdir -p /tmp/docker-compose/").append(dirName).append(" && ");
        
        // 将Compose配置写入文件
        command.append("cat > /tmp/docker-compose/").append(dirName).append("/docker-compose.yml << 'EOT'\n");
        command.append(composeConfig).append("\nEOT\n");
        
        // 创建enabled_plugins文件（如果rabbitMQ模板需要）
        if (composeConfig.contains("./enabled_plugins:/etc/rabbitmq/enabled_plugins")) {
            command.append("cat > /tmp/docker-compose/").append(dirName).append("/enabled_plugins << 'EOT'\n");
            command.append("[rabbitmq_management].\nEOT\n");
        }
        
        // 执行docker-compose命令，支持两种命令格式
        command.append("cd /tmp/docker-compose/").append(dirName).append(" && ");
        command.append("(docker-compose up -d || docker compose up -d)");
        
        return command.toString();
    }
    
    /**
     * 使用普通Docker模式创建容器
     * 
     * @param template Docker模板
     * @param containerName 容器名称
     * @param customParams 自定义参数
     * @return 命令字符串
     */
    private String createContainerWithDocker(SysDockerTemplate template, String containerName, Map<String, String> customParams)
    {
        StringBuilder setupCommand = new StringBuilder();
        
        // 提取卷映射，创建目录并设置权限
        if (StringUtils.isNotEmpty(template.getVolumeMappings()))
        {
            String customVolumes = customParams != null ? customParams.get("volumeMappings") : null;
            String volumes = customVolumes != null ? customVolumes : template.getVolumeMappings();
            
            for (String volumeMapping : volumes.split(","))
            {
                if (StringUtils.isNotEmpty(volumeMapping) && volumeMapping.contains(":"))
                {
                    String hostPath = volumeMapping.substring(0, volumeMapping.indexOf(":"));
                    if (hostPath.startsWith("/")) {
                        setupCommand.append("mkdir -p ").append(hostPath).append(" && ");
                        setupCommand.append("chmod -R 777 ").append(hostPath).append(" && ");
                    }
                }
            }
        }
        
        // 特殊处理Elasticsearch的虚拟内存限制
        if (template.getImageName().toLowerCase().contains("elasticsearch")) {
            setupCommand.append("sysctl -w vm.max_map_count=262144 || true && ");
        }
        
        // 构建 docker run 命令
        StringBuilder runCommand = new StringBuilder("docker run -d");
        
        // 处理容器名称
        if (StringUtils.isNotEmpty(containerName))
        {
            runCommand.append(" --name ").append(containerName);
        }
        else
        {
            runCommand.append(" --name ").append(template.getTemplateName()).append("-").append(System.currentTimeMillis());
        }
        
        // 处理端口映射
        if (StringUtils.isNotEmpty(template.getPortMappings()))
        {
            String customPorts = customParams != null ? customParams.get("portMappings") : null;
            String ports = customPorts != null ? customPorts : template.getPortMappings();
            
            for (String portMapping : ports.split(","))
            {
                if (StringUtils.isNotEmpty(portMapping))
                {
                    runCommand.append(" -p ").append(portMapping);
                }
            }
        }
        
        // 处理卷映射
        if (StringUtils.isNotEmpty(template.getVolumeMappings()))
        {
            String customVolumes = customParams != null ? customParams.get("volumeMappings") : null;
            String volumes = customVolumes != null ? customVolumes : template.getVolumeMappings();
            
            for (String volumeMapping : volumes.split(","))
            {
                if (StringUtils.isNotEmpty(volumeMapping))
                {
                    runCommand.append(" -v ").append(volumeMapping);
                }
            }
        }
        
        // 处理环境变量
        if (StringUtils.isNotEmpty(template.getEnvironmentVars()))
        {
            String customEnvs = customParams != null ? customParams.get("environmentVars") : null;
            String envs = customEnvs != null ? customEnvs : template.getEnvironmentVars();
            
            for (String env : envs.split(","))
            {
                if (StringUtils.isNotEmpty(env))
                {
                    runCommand.append(" -e ").append(env);
                }
            }
        }
        
        // 处理网络模式
        if (StringUtils.isNotEmpty(template.getNetworkMode()))
        {
            runCommand.append(" --network ").append(template.getNetworkMode());
        }
        
        // 处理重启策略
        if (StringUtils.isNotEmpty(template.getRestartPolicy()))
        {
            runCommand.append(" --restart ").append(template.getRestartPolicy());
        }
        
        // 添加镜像名称和标签
        runCommand.append(" ").append(template.getImageName());
        if (StringUtils.isNotEmpty(template.getImageTag()))
        {
            runCommand.append(":").append(template.getImageTag());
        }
        
        // 添加命令
        if (StringUtils.isNotEmpty(template.getCommand()))
        {
            runCommand.append(" ").append(template.getCommand());
        }
        
        // 合并设置命令和运行命令
        if (setupCommand.length() > 0) {
            return setupCommand.toString() + runCommand.toString();
        } else {
            return runCommand.toString();
        }
    }
} 